#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
# @version: v1.0
# @author : wlis
# @Email : 19688513@qq.com
# @Project : g-carbon-bio
# @File : main.py
# @Software: PyCharm
# @time: 2025/1/26 11:19
# @description : 主函数
"""
import datetime

from apscheduler.schedulers.background import BackgroundScheduler
import time
import akshare as ak
from datetime import date
from email_notifier.email_report_generator import EmailReportGenerator
from email_notifier.email_service import EmailService
from service.stock_data_manager import StockDataManager
from service.trade_date_calendar import TradeDateCalendar
from strategies.custom_strategy import CustomStrategy
from strategies.stock_spot_fetcher import StockSpotFetcher

# 初始化调度器
scheduler = BackgroundScheduler()

def fetch_and_insert_morning_stock_data():
    """
    每天早上 9:45 获取并插入上海和深圳的股票数据
    """
    # 初始化服务
    trade_calendar = TradeDateCalendar()
    fetcher = StockSpotFetcher()
    email_service = EmailService()  # 初始化 EmailService
    report_generator = EmailReportGenerator()

    # 获取当前日期
    test_date = datetime.date.today()  # 动态获取当前日期

    try:
        # 检查是否为交易日
        if not trade_calendar.is_tool_trading_day(test_date):
            print(f"{test_date} 不是交易日，跳过数据获取。")
            return

        fetcher.insert_stock_sh_spot_am()  # 插入上海股票数据
        fetcher.insert_stock_sz_spot_am()  # 插入深圳股票数据
        print("早晨股票数据插入成功！")  # 打印成功信息
    except Exception as e:
        error_message = str(e)
        error_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        error_details = [
            {"title": "发生错误", "description": error_message},
            {"title": "方法名称", "description": "fetch_and_insert_morning_stock_data"},
            {"title": "股票数据插入", "description": "获取并插入早晨股票数据时发生错误"},
        ]

        # 生成 HTML 内容
        html_content = report_generator.generate_error_report_html(error_message, error_time, error_details)

        # 发送错误报告邮件
        recipient = '19688513@qq.com'  # 定义收件人
        subject = "股票数据插入错误报告"
        email_title = "股票数据系统"
        email_service.send_email(recipient, subject, email_title, html_content)

def fetch_and_store_evening_stock_data():
    """
    每天晚上 23:59 获取股票数据并存储交易日期
    """
    # 初始化服务
    trade_calendar = TradeDateCalendar()
    stock_data_manager = StockDataManager()
    email_service = EmailService()  # 初始化 EmailService
    report_generator = EmailReportGenerator()

    # 获取当前日期
    test_date = datetime.date.today()  # 动态获取当前日期

    try:
        # 检查是否为交易日
        if not trade_calendar.is_tool_trading_day(test_date):
            print(f"{test_date} 不是交易日，跳过数据获取。")
            return

        stock_data_manager.fetch_stock_data()  # 获取股票数据
        trade_calendar.fetch_and_store_trade_dates()  # 获取并存储交易日期数据
        print("晚间股票数据获取成功！")  # 打印成功信息
    except Exception as e:
        error_message = str(e)
        error_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        error_details = [
            {"title": "发生错误", "description": error_message},
            {"title": "方法名称", "description": "fetch_and_store_evening_stock_data"},
            {"title": "股票数据获取", "description": "获取股票数据时发生错误"},
        ]

        # 生成 HTML 内容
        html_content = report_generator.generate_error_report_html(error_message, error_time, error_details)

        # 发送错误报告邮件
        recipient = '19688513@qq.com'  # 定义收件人
        subject = "股票数据获取错误报告"
        email_title = "股票数据系统"
        email_service.send_email(recipient, subject, email_title, html_content)

def scheduled_fetch_morning_stock_data():
    """
    每天早上 10:30 获取股票数据并发送推荐
    """
    # 初始化服务
    trade_calendar = TradeDateCalendar()
    stock_data_manager = StockDataManager()
    report_generator = EmailReportGenerator()
    email_service = EmailService()

    # 获取当前日期
    test_date = datetime.date.today()  # 动态获取当前日期

    try:
        # 检查是否为交易日
        if not trade_calendar.is_tool_trading_day(test_date):
            print(f"{test_date} 不是交易日，跳过数据获取。")
            return

        email_log_model = []  # 初始化日志模型

        # 获取当前A股市场数据
        stock_df_sh = ak.stock_sh_a_spot_em()
        time.sleep(5)
        stock_df_sz = ak.stock_sz_a_spot_em()
        time.sleep(5)

        # 读取所有股票数据
        stock_all = stock_data_manager.read_stock_data()
        industry_fund_flow_data = CustomStrategy.get_stock_fund_flow_industry_data()

        # 执行筛选策略以获取个股和推荐股票
        individual_stocks_sh, recommended_stocks_sh = CustomStrategy.get_filtered_stocks(stock_df_sh, stock_all, "sh")
        individual_stocks_sz, recommended_stocks_sz = CustomStrategy.get_filtered_stocks(stock_df_sz, stock_all, "sz")

        # 记录日志
        email_log_model = {
            "email_day": test_date.strftime("%Y-%m-%d"),
            "update_log": [
                {"title": "Top_行业资金流", "readme": "资金流向-行业资金流", "changes": industry_fund_flow_data},
                {"title": "上海 三日行情", "readme": "前3日的跌,当日涨", "changes": individual_stocks_sh},
                {"title": "深圳 三日行情", "readme": "前3日的跌,当日涨", "changes": individual_stocks_sz},
                {"title": "推荐上海 成交量行情", "readme": "标注成交量", "changes": recommended_stocks_sh},
                {"title": "推荐深圳 成交量行情", "readme": "标注成交量", "changes": recommended_stocks_sz}
            ]
        }

        # 生成 HTML 报告
        html_report = report_generator.generate_daily_recommendation_html(email_log_model)

        # 定义收件人
        recipient = [['19688513@qq.com', '401252058@qq.com'], ['286196043@qq.com', '354531800@qq.com']]

        # 获取当前时间并设置邮件标题
        now = datetime.datetime.now()
        current_hour = now.hour
        if 0 <= current_hour < 12:
            email_title = "每日上午推荐 - " + now.strftime("%Y-%m-%d")
        elif 12 <= current_hour < 15:
            email_title = "每日下午推荐 - " + now.strftime("%Y-%m-%d")
        else:
            email_title = "每日收盘推荐 - " + now.strftime("%Y-%m-%d")

        subject = "每日推荐邮件" + now.strftime("%Y-%m-%d")

        # 发送邮件
        # 发送邮件，循环遍历收件人
        for recipient_group in recipient:
            email_service.send_email(recipient_group, subject, email_title, html_report)
            print("邮件发送成功！")  # 打印成功信息
            time.sleep(30)  # 等待30秒后再发送下一封邮件

    except Exception as e:
        # 捕获异常并生成错误报告
        error_message = str(e)
        error_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        error_details = [
            {"title": "发送邮件发生错误", "description": error_message},
            {"title": "方法名称", "description": "scheduled_fetch_morning_stock_data"},
            {"title": "邮件主题", "description": "发送策略出现问题"},
        ]

        # 生成错误报告 HTML 内容
        html_content = report_generator.generate_error_report_html(error_message, error_time, error_details)

        # 发送错误报告邮件
        error_recipient = '19688513@qq.com'  # 定义收件人
        error_subject = "邮件发送错误报告"
        email_service.send_email(error_recipient, error_subject, "错误报告", html_content)

        print("邮件发送失败，错误报告已发送！")  # 打印失败信息


# 每天早上 9:45 执行的任务
scheduler.add_job(fetch_and_insert_morning_stock_data, 'cron', hour=9, minute=45, id='fetch_morning_stock_data')

# 每天早上 10:15 执行的任务
scheduler.add_job(scheduled_fetch_morning_stock_data, 'cron', hour=10, minute=15, id='fetch_morning_stock_data_later')

# 每天下午 14:15 执行的任务
scheduler.add_job(scheduled_fetch_morning_stock_data, 'cron', hour=17, minute=48, id='fetch_afternoon_stock_data')

# 每天晚上 22:59 执行的任务
scheduler.add_job(fetch_and_store_evening_stock_data, 'cron', hour=22, minute=59, id='fetch_evening_stock_data')

if __name__ == "__main__":
    print("启动任务调度器...")
    scheduler.start()

    try:
        # 保持主线程运行
        while True:
            time.sleep(1)  # 使用 sleep 减少 CPU 占用
    except (KeyboardInterrupt, SystemExit):
        print("停止任务调度器...")
        scheduler.shutdown()
